home *** CD-ROM | disk | FTP | other *** search
/ Express Pd: GALORE / Express Pd Galore - The Amiga PD & Shareware CD (1994)(Express Pd)[!][Amiga-CD32-CDTV].iso / productivity / term / termxpr.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  57KB  |  2,527 lines

  1. /*
  2. **    termXPR.c
  3. **
  4. **    External transfer protocol support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* How many options xpr_options() will display in a single column. */
  13.  
  14. #define OPTION_WRAP     16
  15.  
  16.     /* These variables keep the transferred bytes and transfer
  17.      * time in seconds.
  18.      */
  19.  
  20. STATIC LONG         ByteVal,
  21.              ByteMax,
  22.              TimeVal,
  23.              TimeMax,
  24.  
  25.              LastTimeDif,
  26.              LastPercent;
  27.  
  28.     /* Transfer statistics. */
  29.  
  30. STATIC ULONG         CPS_Minimum,
  31.              CPS_Maximum,
  32.              CPS_Average,
  33.              CPS_Current,
  34.              CPS_Count,
  35.              CPS_Last;
  36.  
  37.     LONG         CPL_Min,
  38.              CPL_Avg,
  39.              CPL_Cur;
  40.  
  41.     /* The name of the file being transmitted, in case the
  42.      * `override transfer path' feature is enabled.
  43.      */
  44.  
  45. STATIC struct Buffer    *CurrentFile;
  46.  
  47.     /* Yet another flag, this one determines whether we already told
  48.      * the user that the file we are currently processing will fit
  49.      * on the destination device.
  50.      */
  51.  
  52. STATIC BYTE         Alerted,
  53.              CarrierMessage;
  54.  
  55.     /* OpenTransferWindow():
  56.      *
  57.      *    Local routine to open the transfer window.
  58.      */
  59.  
  60. STATIC BYTE
  61. OpenTransferWindow(VOID)
  62. {
  63.         /* Block window input. */
  64.  
  65.     BlockWindows();
  66.  
  67.         /* Try to open the transfer window panel. */
  68.  
  69.     if(TransferPanel(LocaleString(MSG_TERMXPR_RECEIVE_FILES_TXT)))
  70.     {
  71.             /* Supply the log text. */
  72.  
  73.         LogAction(LocaleString(MSG_TERMXPR_LOGMSG_INITIATE_BINARY_DOWNLOAD_TXT));
  74.  
  75.             /* Return success. */
  76.  
  77.         return(TRUE);
  78.     }
  79.     else
  80.     {
  81.             /* Re-enable window input. */
  82.  
  83.         ReleaseWindows();
  84.  
  85.             /* Return failure. */
  86.  
  87.         return(FALSE);
  88.     }
  89. }
  90.  
  91.     /* NewFileName(STRPTR Source,STRPTR Buffer):
  92.      *
  93.      *    Build a valid file and path name, including path
  94.      *    substitution, etc.
  95.      */
  96.  
  97. STATIC STRPTR __regargs
  98. NewFileName(STRPTR Source,STRPTR Buffer)
  99. {
  100.     if(Config -> MiscConfig -> OverridePath && !Uploading)
  101.     {
  102.         if(DownloadPath)
  103.             strcpy(Buffer,DownloadPath);
  104.         else
  105.             strcpy(Buffer,Config -> PathConfig -> BinaryDownloadPath);
  106.  
  107.         if(!Buffer[0])
  108.         {
  109.             if(!GetCurrentDirName(Buffer,MAX_FILENAME_LENGTH))
  110.                 Buffer[0] = 0;
  111.         }
  112.  
  113.         if(Buffer[0])
  114.         {
  115.             if(AddPart(Buffer,FilePart(Source),MAX_FILENAME_LENGTH))
  116.                 return(Buffer);
  117.         }
  118.     }
  119.     else
  120.     {
  121.         if(FilePart(Source) == Source)
  122.         {
  123.             if(GetCurrentDirName(Buffer,MAX_FILENAME_LENGTH))
  124.             {
  125.                 if(AddPart(Buffer,Source,MAX_FILENAME_LENGTH))
  126.                     return(Buffer);
  127.             }
  128.         }
  129.     }
  130.  
  131.     return(Source);
  132. }
  133.  
  134.     /* IdentifySource(STRPTR Name,STRPTR BBSName,struct DateStamp *OpenDate):
  135.      *
  136.      *    Attach source information (BBS name, date and time) to a file.
  137.      */
  138.  
  139. STATIC VOID __inline
  140. IdentifySource(STRPTR Name,STRPTR BBSName,struct DateStamp *OpenDate)
  141. {
  142.     UBYTE        SharedBuffer[MAX_FILENAME_LENGTH],
  143.             Time[20],
  144.             Date[20];
  145.     struct DateTime    DateTime;
  146.  
  147.     memcpy(&DateTime . dat_Stamp,OpenDate,sizeof(struct DateStamp));
  148.  
  149.         /* Prepare for date conversion. */
  150.  
  151.     DateTime . dat_Format    = FORMAT_DOS;
  152.     DateTime . dat_Flags    = 0;
  153.     DateTime . dat_StrDay    = NULL;
  154.     DateTime . dat_StrDate    = Date;
  155.     DateTime . dat_StrTime    = Time;
  156.  
  157.         /* Convert the date. */
  158.  
  159.     if(DateToStr(&DateTime))
  160.     {
  161.         if(BBSName[0])
  162.             SPrintf(SharedBuffer,"%s %s %s",BBSName,Date,Time);
  163.         else
  164.             SPrintf(SharedBuffer,"%s %s",Date,Time);
  165.  
  166.         SetComment(Name,SharedBuffer);
  167.     }
  168. }
  169.  
  170.     /* GetSeconds(STRPTR String):
  171.      *
  172.      *    Tries to turn a string of the format hh:mm:ss into
  173.      *    an integer number.
  174.      */
  175.  
  176. STATIC LONG __inline
  177. GetSeconds(STRPTR String)
  178. {
  179.     UBYTE    Buffer[20];
  180.     LONG    Seconds = 0;
  181.  
  182.     memset(Buffer,0,20);
  183.  
  184.     strcpy(Buffer,String);
  185.  
  186.     Seconds += Atol(&Buffer[6]);
  187.  
  188.     Buffer[5] = 0;
  189.  
  190.     Seconds += Atol(&Buffer[3]) * 60;
  191.  
  192.     Buffer[2] = 0;
  193.  
  194.     Seconds += Atol(&Buffer[0]) * 3600;
  195.  
  196.     return(Seconds);
  197. }
  198.  
  199.     /* TruncateName(STRPTR FileName):
  200.      *
  201.      *    Truncates a file name to a maximum of 48 characters.
  202.      */
  203.  
  204. STATIC STRPTR __inline
  205. TruncateName(STRPTR FileName)
  206. {
  207.     WORD Len = strlen(FileName);
  208.  
  209.     if(Len > 48)
  210.     {
  211.         WORD i;
  212.  
  213.         for(i = Len - 48 ; i < Len ; i++)
  214.         {
  215.             if(i >= Len - 44 && FileName[i] == '/')
  216.             {
  217.                 STATIC UBYTE NameBuffer[MAX_FILENAME_LENGTH];
  218.  
  219.                 strcpy(NameBuffer,".../");
  220.  
  221.                 strcat(NameBuffer,&FileName[i + 1]);
  222.  
  223.                 return(NameBuffer);
  224.             }
  225.         }
  226.     }
  227.  
  228.     return(FileName);
  229. }
  230.  
  231.     /* CalculateBlocks(LONG Size,LONG BlockSize):
  232.      *
  233.      *    Calculate the number of blocks a file will
  234.      *    occupy if saved to a disk.
  235.      */
  236.  
  237. STATIC LONG __inline
  238. CalculateBlocks(LONG Size,LONG BlockSize)
  239. {
  240.     LONG    Blocks        = 1;        /* One for the file header. */
  241.     BYTE    HasExtension    = FALSE,    /* No extension block yet. */
  242.         Extension    = 0;        /* How many block pointers yet. */
  243.  
  244.         /* Round to next block. */
  245.  
  246.     Size = ((Size + BlockSize - 1) / BlockSize) * BlockSize;
  247.  
  248.     while(Size)
  249.     {
  250.             /* Add another block. */
  251.  
  252.         Blocks++;
  253.  
  254.             /* Subtract another block. */
  255.  
  256.         Size -= BlockSize;
  257.  
  258.             /* Add another block pointer, if 72 have been
  259.              * added, add another extension block.
  260.              */
  261.  
  262.         if((Extension++) == 72)
  263.         {
  264.                 /* If no extension block has been generated
  265.                  * yet, we were running on the block pointers
  266.                  * of the file header itself.
  267.                  */
  268.  
  269.             if(!HasExtension)
  270.                 HasExtension = TRUE;
  271.             else
  272.                 Blocks++;
  273.  
  274.                 /* Reset extension block counter. */
  275.  
  276.             Extension = 0;
  277.         }
  278.     }
  279.  
  280.     return(Blocks);
  281. }
  282.  
  283.     /* GetOptionMode(struct xpr_option *Option):
  284.      *
  285.      *    Turn text into a boolean value.
  286.      */
  287.  
  288. STATIC BYTE __inline
  289. GetOptionMode(struct xpr_option *Option)
  290. {
  291.     if(Option)
  292.     {
  293.         STATIC STRPTR TrueOptions[] =
  294.         {
  295.             "ON",
  296.             "TRUE",
  297.             "T",
  298.             "YES",
  299.             "Y",
  300.             NULL
  301.         };
  302.  
  303.         register WORD i;
  304.  
  305.         for(i = 0 ; TrueOptions[i] ; i++)
  306.         {
  307.             if(!Stricmp(Option -> xpro_value,TrueOptions[i]))
  308.                 return(TRUE);
  309.         }
  310.     }
  311.  
  312.     return(FALSE);
  313. }
  314.  
  315.     /* CreateAllOptionGadgets():
  316.      *
  317.      *    Create all the gadgets for the xpr options control panel.
  318.      */
  319.  
  320. STATIC struct Gadget *
  321. CreateAllOptionGadgets(LONG *Count,LONG NumOpts,struct xpr_option *Opts[],struct Gadget *GadgetArray[],struct Gadget **GadgetList,APTR VisualInfo)
  322. {
  323.     struct Gadget        *Gadget;
  324.     struct NewGadget     NewGadget;
  325.     LONG             i,MaxLength = 0,MaxLength1 = 0,MaxWidth,MaxWidth1,Len,NumOptsSmall;
  326.     BYTE             WrapIt = FALSE;
  327.  
  328.     SZ_SizeSetup(Window -> WScreen,&UserFont,TRUE);
  329.  
  330.     memset(&NewGadget,0,sizeof(struct NewGadget));
  331.  
  332.     *Count = 0;
  333.  
  334.     SZ_ResetMaxWidth();
  335.  
  336.     if(Gadget = CreateContext(GadgetList))
  337.     {
  338.         NewGadget . ng_TextAttr        = &UserFont;
  339.         NewGadget . ng_VisualInfo    = VisualInfo;
  340.         NewGadget . ng_Flags        = NG_HIGHLABEL;
  341.  
  342.             /* Precalculate gadget left edge offset. */
  343.  
  344.         if((NumOptsSmall = NumOpts) > OPTION_WRAP)
  345.             NumOptsSmall = OPTION_WRAP;
  346.  
  347.         for(i = 0 ; i < NumOptsSmall ; i++)
  348.         {
  349.             if(Opts[i])
  350.             {
  351.                 switch(Opts[i] -> xpro_type)
  352.                 {
  353.                     case XPRO_BOOLEAN:
  354.  
  355.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  356.                             MaxLength = Len;
  357.  
  358.                         SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
  359.  
  360.                         break;
  361.  
  362.                     case XPRO_HEADER:
  363.  
  364.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  365.                             MaxLength = Len;
  366.  
  367.                         break;
  368.  
  369.                     case XPRO_LONG:
  370.                     case XPRO_STRING:
  371.                     case XPRO_COMMPAR:
  372.  
  373.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength)
  374.                             MaxLength = Len;
  375.  
  376.                         SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
  377.  
  378.                         break;
  379.  
  380.                     case XPRO_COMMAND:
  381.  
  382.                         SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
  383.  
  384.                         break;
  385.  
  386.                     default:
  387.  
  388.                         break;
  389.                 }
  390.             }
  391.         }
  392.  
  393.         MaxWidth = SZ_ResetMaxWidth();
  394.  
  395.         SZ_AddLeftOffset(MaxLength + INTERWIDTH);
  396.  
  397.         for(i = OPTION_WRAP ; i < NumOpts ; i++)
  398.         {
  399.             if(Opts[i])
  400.             {
  401.                 switch(Opts[i] -> xpro_type)
  402.                 {
  403.                     case XPRO_BOOLEAN:
  404.  
  405.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  406.                             MaxLength1 = Len;
  407.  
  408.                         SZ_UpdateMaxWidth(CHECKBOX_KIND,NULL,0,NULL);
  409.  
  410.                         break;
  411.  
  412.                     case XPRO_HEADER:
  413.  
  414.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  415.                             MaxLength1 = Len;
  416.  
  417.                         break;
  418.  
  419.                     case XPRO_LONG:
  420.                     case XPRO_STRING:
  421.                     case XPRO_COMMPAR:
  422.  
  423.                         if((Len = SZ_TextWidth(Opts[i] -> xpro_description)) > MaxLength1)
  424.                             MaxLength1 = Len;
  425.  
  426.                         SZ_UpdateMaxWidth(STRING_KIND,NULL,20,NULL);
  427.  
  428.                         break;
  429.  
  430.                     case XPRO_COMMAND:
  431.  
  432.                         SZ_UpdateMaxWidth(TEXT_KIND,Opts[i] -> xpro_description,0,NULL);
  433.  
  434.                         break;
  435.  
  436.                     default:
  437.  
  438.                         break;
  439.                 }
  440.             }
  441.         }
  442.  
  443.         MaxWidth1 = SZ_ResetMaxWidth();
  444.  
  445.         SZ_SetWidth(MaxWidth);
  446.  
  447.         for(i = 0 ; i < NumOpts ; i++)
  448.         {
  449.             if(i == OPTION_WRAP + 1)
  450.                 WrapIt = TRUE;
  451.  
  452.             if(!Opts[i])
  453.                 continue;
  454.  
  455.             if(WrapIt)
  456.             {
  457.                 SZ_SetWidth(MaxWidth1);
  458.                 SZ_AddLeftOffset(MaxLength1 + INTERWIDTH);
  459.             }
  460.  
  461.             switch(Opts[i] -> xpro_type)
  462.             {
  463.                 case XPRO_BOOLEAN:
  464.  
  465.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  466.                     NewGadget . ng_GadgetID        = i;
  467.  
  468.                     GadgetArray[i] = Gadget = CreateGadget(CHECKBOX_KIND,Gadget,&NewGadget,
  469.                         SZ_Adjust,    TRUE,
  470.                         SZ_AutoWidth,    TRUE,
  471.                         SZ_NewColumn,    WrapIt,
  472.  
  473.                         GTCB_Checked,    GetOptionMode(Opts[i]),
  474.                     TAG_DONE);
  475.  
  476.                     break;
  477.  
  478.                 case XPRO_LONG:
  479.  
  480.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  481.                     NewGadget . ng_GadgetID        = i;
  482.  
  483.                     GadgetArray[i] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
  484.                         SZ_Adjust,    TRUE,
  485.                         SZ_AutoWidth,    TRUE,
  486.                         SZ_NewColumn,    WrapIt,
  487.  
  488.                         GTIN_Number,    Atol(Opts[i] -> xpro_value),
  489.                         GTST_EditHook,    &CommandHook,
  490.                     TAG_DONE);
  491.  
  492.                     break;
  493.  
  494.                 case XPRO_STRING:
  495.                 case XPRO_COMMPAR:
  496.  
  497.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  498.                     NewGadget . ng_GadgetID        = i;
  499.  
  500.                     GadgetArray[i] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  501.                         SZ_Adjust,    TRUE,
  502.                         SZ_AutoWidth,    TRUE,
  503.                         SZ_NewColumn,    WrapIt,
  504.  
  505.                         GTST_String,    Opts[i] -> xpro_value,
  506.                         GTST_MaxChars,    Opts[i] -> xpro_length - 1,
  507.                         GTST_EditHook,    &CommandHook,
  508.                     TAG_DONE);
  509.  
  510.                     break;
  511.  
  512.                 case XPRO_HEADER:
  513.  
  514.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  515.                     NewGadget . ng_GadgetID        = i;
  516.                     NewGadget . ng_Flags        = NG_HIGHLABEL;
  517.  
  518.                     GadgetArray[i] = Gadget = CreateGadget(TEXT_KIND,Gadget,&NewGadget,
  519.                         SZ_Adjust,    TRUE,
  520.                         SZ_AutoWidth,    TRUE,
  521.  
  522.                         GTTX_Text,    " ",
  523.                     TAG_DONE);
  524.  
  525.                     NewGadget . ng_Flags = 0;
  526.  
  527.                     break;
  528.  
  529.                 case XPRO_COMMAND:
  530.  
  531.                     NewGadget . ng_GadgetText    = Opts[i] -> xpro_description;
  532.                     NewGadget . ng_GadgetID        = i;
  533.  
  534.                     GadgetArray[i] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  535.                         SZ_Adjust,    TRUE,
  536.                         SZ_AutoWidth,    TRUE,
  537.                     TAG_DONE);
  538.  
  539.                     break;
  540.  
  541.                 default:break;
  542.             }
  543.  
  544.             WrapIt = FALSE;
  545.         }
  546.  
  547.         SZ_ResetMaxWidth();
  548.  
  549.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_SAVE_GAD),0,NULL);
  550.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
  551.  
  552.         SZ_SetWidth(SZ_ResetMaxWidth());
  553.  
  554.         NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_SAVE_GAD);
  555.         NewGadget . ng_GadgetID        = GAD_XPROPTIONS_USE;
  556.  
  557.         GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  558.             SZ_AlignExtra,    TRUE,
  559.             SZ_Adjust,    TRUE,
  560.             SZ_AutoWidth,    TRUE,
  561.             SZ_AlignLeft,    TRUE,
  562.             SZ_AlignBottom,    TRUE,
  563.  
  564.             GT_Underscore,    '_',
  565.         TAG_DONE);
  566.  
  567.         NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_CANCEL_GAD);
  568.         NewGadget . ng_GadgetID        = GAD_XPROPTIONS_CANCEL;
  569.  
  570.         GadgetArray[i++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  571.             SZ_Adjust,    TRUE,
  572.             SZ_AutoWidth,    TRUE,
  573.             SZ_AlignRight,    TRUE,
  574.  
  575.             GT_Underscore,    '_',
  576.         TAG_DONE);
  577.  
  578.         if(Gadget)
  579.             *Count = i;
  580.     }
  581.  
  582.     return(Gadget);
  583. }
  584.  
  585.     /* SerialErrorReport(struct IOExtSer *Request):
  586.      *
  587.      *    Report a certain I/O error cause.
  588.      */
  589.  
  590. STATIC BYTE __regargs
  591. SerialErrorReport(struct IOExtSer *Request)
  592. {
  593.     STRPTR    ErrorMessage;
  594.     BYTE    IsFatal;
  595.  
  596.     switch(Request -> IOSer . io_Error)
  597.     {
  598.         case SerErr_LineErr:
  599.  
  600.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_HARDWARE_DATA_OVERRUN_TXT);
  601.  
  602.             IsFatal = FALSE;
  603.  
  604.             break;
  605.  
  606.         case SerErr_ParityErr:
  607.  
  608.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_PARITY_ERROR_TXT);
  609.  
  610.             IsFatal = TRUE;
  611.  
  612.             break;
  613.  
  614.         case SerErr_TimerErr:
  615.  
  616.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_TIMER_ERROR_TXT);
  617.  
  618.             IsFatal = FALSE;
  619.  
  620.             break;
  621.  
  622.         case SerErr_BufOverflow:
  623.  
  624.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_READ_BUFFER_OVERFLOWED_TXT);
  625.  
  626.             IsFatal = FALSE;
  627.  
  628.             break;
  629.  
  630.         case SerErr_NoDSR:
  631.  
  632.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_NO_DSR_TXT);
  633.  
  634.             IsFatal = TRUE;
  635.  
  636.             break;
  637.  
  638.         case SerErr_DetectedBreak:
  639.  
  640.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_BREAK_DETECTED_TXT);
  641.  
  642.             IsFatal = TRUE;
  643.  
  644.             break;
  645.  
  646.         default:
  647.  
  648.             ErrorMessage = LocaleString(MSG_TERMXPR_ERROR_UNKNOWN_CAUSE_TXT);
  649.  
  650.             IsFatal = FALSE;
  651.  
  652.             break;
  653.     }
  654.  
  655.     AddTransferInfo(LocaleString(MSG_TERMXPR_ERROR_TEMPLATE_TXT),Request -> IOSer . io_Error,ErrorMessage);
  656.  
  657.     if(IsFatal)
  658.     {
  659.         TransferError = TRUE;
  660.  
  661.         return(TRUE);
  662.     }
  663.     else
  664.         return(FALSE);
  665. }
  666.  
  667.     /* xpr_fopen(STRPTR FileName,STRPTR AccessMode):
  668.      *
  669.      *    Open a file for random access.
  670.      */
  671.  
  672. LONG __saveds __asm
  673. xpr_fopen(register __a0 STRPTR FileName,register __a1 STRPTR AccessMode)
  674. {
  675.     UBYTE         RealName[MAX_FILENAME_LENGTH];
  676.     struct Buffer    *File;
  677.  
  678.     Alerted = CarrierMessage = FALSE;
  679.  
  680.         /* Reset transfer counters. */
  681.  
  682.     ByteVal = ByteMax = TimeVal = TimeMax = LastTimeDif = 0;
  683.  
  684.     LastPercent = -1;
  685.  
  686.         /* Reset CPS statistics. */
  687.  
  688.     CPS_Minimum    = (ULONG)~0;
  689.     CPS_Maximum    = 0;
  690.     CPS_Average    = 0;
  691.     CPS_Current    = 0;
  692.     CPS_Count    = 0;
  693.     CPS_Last    = 0;
  694.  
  695.         /* No window available for output? */
  696.  
  697.     if(!TransferWindow)
  698.         OpenTransferWindow();
  699.  
  700.         /* Disable the time and data bars in the transfer window. */
  701.  
  702.     if(TransferWindow)
  703.     {
  704.         GhostStats(TransferGadgetArray[GAD_TRANSFER_PERCENT]);
  705.         GhostStats(TransferGadgetArray[GAD_TRANSFER_TIME]);
  706.     }
  707.  
  708.         /* Determine the file name. */
  709.  
  710.     FileName = NewFileName(FileName,RealName);
  711.  
  712.         /* Determine file transfer mode... */
  713.  
  714.     if(File = BufferOpen(FileName,AccessMode))
  715.     {
  716.         switch(AccessMode[0])
  717.         {
  718.             case 'r':
  719.  
  720.                 LogAction(LocaleString(MSG_TERMXPR_LOGMSG_SEND_FILE_TXT),FileName);
  721.                 break;
  722.  
  723.             case 'w':
  724.  
  725.                 LogAction(LocaleString(MSG_TERMXPR_LOGMSG_RECEIVE_FILE_TXT),FileName);
  726.                 break;
  727.  
  728.             case 'a':
  729.  
  730.                 LogAction(LocaleString(MSG_TERMXPR_LOGMSG_UPDATE_FILE_TXT),FileName);
  731.                 break;
  732.         }
  733.  
  734.         CurrentFile = File;
  735.     }
  736.  
  737.     DidTransfer = TRUE;
  738.  
  739.     return((LONG)File);
  740. }
  741.  
  742.     /* xpr_fclose(struct Buffer *File):
  743.      *
  744.      *    Close a file opened by xpr_fopen.
  745.      */
  746.  
  747. LONG __saveds __asm
  748. xpr_fclose(register __a0 struct Buffer *File)
  749. {
  750.     UBYTE            RealName[MAX_FILENAME_LENGTH];
  751.     struct DateStamp    OpenDate;
  752.     BYTE            WriteAccess,
  753.                 Used;
  754.  
  755.         /* Save some information. */
  756.  
  757.     OpenDate    = File -> OpenDate;
  758.     WriteAccess    = File -> WriteAccess;
  759.     Used        = File -> Used;
  760.  
  761.         /* Get the name of the file. */
  762.  
  763.     if(!NameFromFH(File -> FileHandle,RealName,MAX_FILENAME_LENGTH))
  764.         RealName[0] = 0;
  765.  
  766.         /* Close the file and see what it brings... */
  767.  
  768.     if(BufferClose(File) && RealName[0])
  769.     {
  770.             /* Did any access take place at all?
  771.              * xprzmodem.library for example just
  772.              * opens and closes a file in order to
  773.              * see if it exists.
  774.              */
  775.  
  776.         if(!Used)
  777.             LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  778.         else
  779.         {
  780.                 /* Did we receive or send a file? */
  781.  
  782.             if(WriteAccess)
  783.             {
  784.                 LONG Size;
  785.  
  786.                     /* Did the file remain empty? */
  787.  
  788.                 if(!(Size = GetFileSize(RealName)))
  789.                 {
  790.                     AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_REMOVED_TXT),FilePart(RealName));
  791.  
  792.                         /* Delete empty file. */
  793.  
  794.                     if(DeleteFile(RealName))
  795.                         LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_REMOVED_TXT),RealName);
  796.                     else
  797.                         LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  798.                 }
  799.                 else
  800.                 {
  801.                     struct Node *SomeNode;
  802.  
  803.                     if(ByteMax)
  804.                     {
  805.                         if(Size >= ByteMax)
  806.                             AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_RECEIVED_TXT),FilePart(RealName));
  807.                         else
  808.                             AddTransferInfo(LocaleString(MSG_TERMXPR_INCOMPLETE_FILE_RECEIVED_TXT),FilePart(RealName));
  809.                     }
  810.  
  811.                         /* Try to identify the file type. */
  812.  
  813.                     switch(Config -> MiscConfig -> IdentifyFiles)
  814.                     {
  815.                         case IDENTIFY_FILETYPE:
  816.  
  817.                             Identify(RealName);
  818.                             break;
  819.  
  820.                         case IDENTIFY_SOURCE:
  821.  
  822.                             IdentifySource(RealName,CurrentBBSName,&OpenDate);
  823.                             break;
  824.                     }
  825.  
  826.                     if(CPS_Minimum == (ULONG)~0)
  827.                         CPS_Minimum = 0;
  828.  
  829.                     if(CPS_Count == 0)
  830.                     {
  831.                         CPS_Average    = 0;
  832.                         CPS_Count    = 1;
  833.                     }
  834.  
  835.                     LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_BYTES_TXT),RealName,Size,CPS_Minimum,CPS_Average / CPS_Count,CPS_Maximum);
  836.  
  837.                     if(SomeNode = CreateGenericListNode(0,RealName))
  838.                         AddGenericListNode(GenericListTable[GLIST_DOWNLOAD],SomeNode,ADD_GLIST_BOTTOM);
  839.                 }
  840.             }
  841.             else
  842.             {
  843.                     /* Set the archived bit on files we uploaded? */
  844.  
  845.                 if(Config -> MiscConfig -> SetArchivedBit)
  846.                 {
  847.                     struct FileInfoBlock *FileInfo;
  848.  
  849.                     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  850.                     {
  851.                         BPTR FileLock;
  852.  
  853.                             /* Get a lock on it. */
  854.  
  855.                         if(FileLock = Lock(RealName,ACCESS_READ))
  856.                         {
  857.                                 /* Examine the file. */
  858.  
  859.                             if(Examine(FileLock,FileInfo))
  860.                             {
  861.                                     /* Remove the lock. */
  862.  
  863.                                 UnLock(FileLock);
  864.  
  865.                                     /* Set the `archived' bit. */
  866.  
  867.                                 SetProtection(RealName,FileInfo -> fib_Protection | FIBF_ARCHIVE);
  868.                             }
  869.                             else
  870.                                 UnLock(FileLock);
  871.                         }
  872.  
  873.                         FreeDosObject(DOS_FIB,FileInfo);
  874.                     }
  875.                 }
  876.  
  877.                 AddTransferInfo(LocaleString(MSG_TERMXPR_FILE_SENT_TXT),FilePart(RealName));
  878.  
  879.                 LogAction(LocaleString(MSG_TERMXPR_CLOSE_FILE_TXT),RealName);
  880.  
  881.                 RemoveUploadListItem(RealName);
  882.             }
  883.         }
  884.     }
  885.  
  886.     CurrentFile = NULL;
  887.  
  888.     return(1);
  889. }
  890.  
  891.     /* xpr_fread(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
  892.      *
  893.      *    Read a few bytes from a file.
  894.      */
  895.  
  896. LONG __saveds __asm
  897. xpr_fread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
  898. {
  899.     return(BufferRead(File,Buffer,Size * Count) / Size);
  900. }
  901.  
  902.     /* xpr_fwrite(APTR Buffer,LONG Size,LONG Count,struct Buffer *File):
  903.      *
  904.      *    Write a few bytes to a file.
  905.      */
  906.  
  907. LONG __saveds __asm
  908. xpr_fwrite(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 LONG Count,register __a1 struct Buffer *File)
  909. {
  910.     return(BufferWrite(File,Buffer,Size * Count) / Size);
  911. }
  912.  
  913.     /* xpr_fseek(struct Buffer *File,LONG Offset,LONG Origin):
  914.      *
  915.      *    Move the read/write pointer in a file.
  916.      */
  917.  
  918. LONG __saveds __asm
  919. xpr_fseek(register __a0 struct Buffer *File,register __d0 LONG Offset,register __d1 LONG Origin)
  920. {
  921.     return(BufferSeek(File,Offset,Origin) ? 0 : -1);
  922. }
  923.  
  924.     /* xpr_sread(APTR Buffer,LONG Size,LONG Timeout):
  925.      *
  926.      *    Read a few bytes from the serial port (including
  927.      *    timeouts).
  928.      */
  929.  
  930. LONG __saveds __asm
  931. xpr_sread(register __a0 APTR Buffer,register __d0 LONG Size,register __d1 ULONG Timeout)
  932. {
  933.         /* No window available for output? */
  934.  
  935.     if(!TransferWindow)
  936.     {
  937.         if(!OpenTransferWindow())
  938.             return(-1);
  939.     }
  940.  
  941.         /* Are both IORequests available? */
  942.  
  943.     if(WriteRequest && ReadRequest)
  944.     {
  945.             /* Valid size parameter? */
  946.  
  947.         if(Size > 0)
  948.         {
  949.                 /* How many bytes are still in the serial buffer? */
  950.  
  951.             WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  952.  
  953.             DoIO(WriteRequest);
  954.  
  955.                 /* Return error if carrier is lost. */
  956.  
  957.             if(Config -> SerialConfig -> CheckCarrier)
  958.             {
  959.                 if(WriteRequest -> io_Status & CIAF_COMCD)
  960.                 {
  961.                     if(!CarrierMessage)
  962.                     {
  963.                         CarrierMessage = TRUE;
  964.  
  965.                         AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
  966.                     }
  967.  
  968.                     Online = FALSE;
  969.  
  970.                     TransferError = TRUE;
  971.  
  972.                     return(-1);
  973.                 }
  974.             }
  975.  
  976.             /* ALWAYS */
  977.             {
  978.                 register ULONG Waiting;
  979.  
  980.                 if(Waiting = WriteRequest -> IOSer . io_Actual)
  981.                 {
  982.                         /* No timeout specified? Read as many
  983.                          * bytes as available.
  984.                          */
  985.  
  986.                     if(!Timeout)
  987.                     {
  988.                         if(Waiting > Size)
  989.                             Waiting = Size;
  990.  
  991.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  992.                         ReadRequest -> IOSer . io_Data        = Buffer;
  993.                         ReadRequest -> IOSer . io_Length    = Waiting;
  994.  
  995.                         if(DoIO(ReadRequest))
  996.                         {
  997.                             if(SerialErrorReport(ReadRequest))
  998.                                 return(-1);
  999.                             else
  1000.                                 Waiting = ReadRequest -> IOSer . io_Actual;
  1001.                         }
  1002.  
  1003.                         BytesIn += Waiting;
  1004.  
  1005.                         return((LONG)Waiting);
  1006.                     }
  1007.  
  1008.                         /* Enough data pending to be read? */
  1009.  
  1010.                     if(Waiting >= Size)
  1011.                     {
  1012.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1013.                         ReadRequest -> IOSer . io_Data        = Buffer;
  1014.                         ReadRequest -> IOSer . io_Length    = Size;
  1015.  
  1016.                         if(DoIO(ReadRequest))
  1017.                         {
  1018.                             if(SerialErrorReport(ReadRequest))
  1019.                                 return(-1);
  1020.                             else
  1021.                                 Size = ReadRequest -> IOSer . io_Actual;
  1022.                         }
  1023.  
  1024.                         BytesIn += Size;
  1025.  
  1026.                         return(Size);
  1027.                     }
  1028.                 }
  1029.                 else
  1030.                 {
  1031.                         /* No timeout & no bytes available:
  1032.                          * return immediately.
  1033.                          */
  1034.  
  1035.                     if(!Timeout)
  1036.                         return(0);
  1037.                 }
  1038.             }
  1039.  
  1040.             /* ALWAYS */
  1041.             {
  1042.                 register ULONG SignalSet,WindowMask = PORTMASK(TransferWindow -> UserPort);
  1043.  
  1044.                     /* Set up the timer. */
  1045.  
  1046.                 TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  1047.                 TimeRequest -> tr_time . tv_secs    = Timeout / MILLION;
  1048.                 TimeRequest -> tr_time . tv_micro    = Timeout % MILLION;
  1049.  
  1050.                     /* Set up the read request. */
  1051.  
  1052.                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1053.                 ReadRequest -> IOSer . io_Data        = Buffer;
  1054.                 ReadRequest -> IOSer . io_Length    = Size;
  1055.  
  1056.                     /* Prevent early termination. */
  1057.  
  1058.                 ClrSignal(SIG_SERIAL | SIG_TIMER);
  1059.  
  1060.                     /* Start IO... */
  1061.  
  1062.                 SendIO(ReadRequest);
  1063.                 SendIO(TimeRequest);
  1064.  
  1065.                 FOREVER
  1066.                 {
  1067.                     SignalSet = Wait(SIG_SERIAL | SIG_TIMER | WindowMask);
  1068.  
  1069.                         /* Abort file transfer? */
  1070.  
  1071.                     if(SignalSet & WindowMask)
  1072.                     {
  1073.                         if(xpr_chkabort() == -1)
  1074.                         {
  1075.                             if(!CheckIO(ReadRequest))
  1076.                                 AbortIO(ReadRequest);
  1077.  
  1078.                             if(!CheckIO(TimeRequest))
  1079.                                 AbortIO(TimeRequest);
  1080.  
  1081.                             WaitIO(ReadRequest);
  1082.                             WaitIO(TimeRequest);
  1083.  
  1084.                             SendAbort = TRUE;
  1085.  
  1086.                             return(-1);
  1087.                         }
  1088.                     }
  1089.  
  1090.                         /* Receive buffer filled? */
  1091.  
  1092.                     if(SignalSet & SIG_SERIAL)
  1093.                     {
  1094.                             /* Abort the timer request. */
  1095.  
  1096.                         if(!CheckIO(TimeRequest))
  1097.                             AbortIO(TimeRequest);
  1098.  
  1099.                         WaitIO(TimeRequest);
  1100.  
  1101.                             /* Did the request terminate gracefully? */
  1102.  
  1103.                         if(WaitIO(ReadRequest))
  1104.                         {
  1105.                             if(SerialErrorReport(ReadRequest))
  1106.                                 return(-1);
  1107.                             else
  1108.                                 Size = ReadRequest -> IOSer . io_Actual;
  1109.                         }
  1110.  
  1111.                         BytesIn += Size;
  1112.  
  1113.                         return(Size);
  1114.                     }
  1115.  
  1116.                         /* Hit by timeout? */
  1117.  
  1118.                     if(SignalSet & SIG_TIMER)
  1119.                     {
  1120.                             /* Abort the read request. */
  1121.  
  1122.                         if(!CheckIO(ReadRequest))
  1123.                             AbortIO(ReadRequest);
  1124.  
  1125.                         WaitIO(ReadRequest);
  1126.  
  1127.                             /* Remove the timer request. */
  1128.  
  1129.                         WaitIO(TimeRequest);
  1130.  
  1131.                             /* Did the driver receive any
  1132.                              * data?
  1133.                              */
  1134.  
  1135.                         if(ReadRequest -> IOSer . io_Actual)
  1136.                         {
  1137.                             BytesIn += ReadRequest -> IOSer . io_Actual;
  1138.  
  1139.                             return((LONG)ReadRequest -> IOSer . io_Actual);
  1140.                         }
  1141.                         else
  1142.                         {
  1143.                                 /* Take a second look and query the number of
  1144.                                  * bytes ready to be received, there may
  1145.                                  * still be some bytes in the buffer.
  1146.                                  * Note: this depends on the way the
  1147.                                  * driver handles read abort.
  1148.                                  */
  1149.  
  1150.                             WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1151.  
  1152.                             DoIO(WriteRequest);
  1153.  
  1154.                                 /* Don't read too much. */
  1155.  
  1156.                             if(Size > WriteRequest -> IOSer . io_Actual)
  1157.                                 Size = WriteRequest -> IOSer . io_Actual;
  1158.  
  1159.                                 /* Are there any bytes to be transferred? */
  1160.  
  1161.                             if(Size)
  1162.                             {
  1163.                                     /* Read the data. */
  1164.  
  1165.                                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1166.                                 ReadRequest -> IOSer . io_Data        = Buffer;
  1167.                                 ReadRequest -> IOSer . io_Length    = Size;
  1168.  
  1169.                                     /* Read the data. */
  1170.  
  1171.                                 if(DoIO(ReadRequest))
  1172.                                 {
  1173.                                     if(SerialErrorReport(ReadRequest))
  1174.                                         return(-1);
  1175.                                     else
  1176.                                         Size = ReadRequest -> IOSer . io_Actual;
  1177.                                 }
  1178.  
  1179.                                 BytesIn += Size;
  1180.                             }
  1181.  
  1182.                             return(Size);
  1183.                         }
  1184.                     }
  1185.                 }
  1186.             }
  1187.         }
  1188.         else
  1189.             return(0);
  1190.     }
  1191.     else
  1192.         return(-1);
  1193. }
  1194.  
  1195.     /* xpr_swrite(APTR Buffer,LONG Size):
  1196.      *
  1197.      *    Write a few bytes to the serial port.
  1198.      */
  1199.  
  1200. LONG __saveds __asm
  1201. xpr_swrite(register __a0 APTR Buffer,register __d0 LONG Size)
  1202. {
  1203.     if(WriteRequest)
  1204.     {
  1205.             /* Return error if carrier is lost. */
  1206.  
  1207.         if(Config -> SerialConfig -> CheckCarrier)
  1208.         {
  1209.                 /* Query the serial status bits. */
  1210.  
  1211.             WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1212.  
  1213.             DoIO(WriteRequest);
  1214.  
  1215.                 /* Is the carrier signal still present? */
  1216.  
  1217.             if(WriteRequest -> io_Status & CIAF_COMCD)
  1218.             {
  1219.                 if(!CarrierMessage)
  1220.                 {
  1221.                     CarrierMessage = TRUE;
  1222.  
  1223.                     AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
  1224.                 }
  1225.  
  1226.                 Online = FALSE;
  1227.  
  1228.                 TransferError = TRUE;
  1229.  
  1230.                 return(-1);
  1231.             }
  1232.         }
  1233.  
  1234.             /* Send the data. */
  1235.  
  1236.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  1237.         WriteRequest -> IOSer . io_Data        = Buffer;
  1238.         WriteRequest -> IOSer . io_Length    = Size;
  1239.  
  1240.         if(DoIO(WriteRequest))
  1241.         {
  1242.             if(SerialErrorReport(WriteRequest))
  1243.                 return(-1);
  1244.         }
  1245.         else
  1246.             BytesOut += Size;
  1247.  
  1248.         return(0);
  1249.     }
  1250.     else
  1251.         return(-1);
  1252. }
  1253.  
  1254.     /* xpr_sflush():
  1255.      *
  1256.      *    Release the contents of all serial buffers.
  1257.      */
  1258.  
  1259. LONG __saveds __asm
  1260. xpr_sflush()
  1261. {
  1262.     if(WriteRequest)
  1263.     {
  1264.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  1265.  
  1266.         if(DoIO(WriteRequest))
  1267.         {
  1268.             if(SerialErrorReport(WriteRequest))
  1269.                 return(-1);
  1270.         }
  1271.  
  1272.         return(0);
  1273.     }
  1274.     else
  1275.         return(-1);
  1276. }
  1277.  
  1278.     /* xpr_update(struct XPR_UPDATE *UpdateInfo):
  1279.      *
  1280.      *    Update the information displayed in the transfer window.
  1281.      */
  1282.  
  1283. LONG __saveds __asm
  1284. xpr_update(register __a0 struct XPR_UPDATE *UpdateInfo)
  1285. {
  1286.         /* No window available for output? */
  1287.  
  1288.     if(!TransferWindow)
  1289.     {
  1290.         if(!OpenTransferWindow())
  1291.             return(0);
  1292.     }
  1293.  
  1294.     if(UpdateInfo)
  1295.     {
  1296.         struct RastPort    *RPort        = TransferWindow -> RPort;
  1297.         BYTE         NewByte    = FALSE,
  1298.                  NewTime    = FALSE;
  1299.  
  1300.         if((UpdateInfo -> xpru_updatemask & XPRU_PROTOCOL) && UpdateInfo -> xpru_protocol)
  1301.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_1],0,UpdateInfo -> xpru_protocol);
  1302.  
  1303.         if((UpdateInfo -> xpru_updatemask & XPRU_MSG) && UpdateInfo -> xpru_msg)
  1304.             AddTransferInfo(UpdateInfo -> xpru_msg);
  1305.  
  1306.         if((UpdateInfo -> xpru_updatemask & XPRU_ERRORMSG) && UpdateInfo -> xpru_errormsg)
  1307.             AddTransferInfo(UpdateInfo -> xpru_errormsg);
  1308.  
  1309.         if((UpdateInfo -> xpru_updatemask & XPRU_FILENAME) && UpdateInfo -> xpru_filename)
  1310.         {
  1311.             UBYTE    RealName[MAX_FILENAME_LENGTH];
  1312.             STRPTR    FileName;
  1313.  
  1314.             FileName = NewFileName(UpdateInfo -> xpru_filename,RealName);
  1315.  
  1316.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],0,TruncateName(FileName));
  1317.  
  1318.             if(FileTransferInfo)
  1319.             {
  1320.                 if(FileTransferInfo -> CurrentFile)
  1321.                 {
  1322.                     struct FileTransferNode *Node = (struct FileTransferNode *)FileTransferInfo -> CurrentFile -> Node . mln_Succ;
  1323.  
  1324.                     if(Node -> Node . mln_Succ)
  1325.                         SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],1,TruncateName(Node -> Name));
  1326.                     else
  1327.                         SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],1,LocaleString(MSG_GLOBAL_NONE_TXT));
  1328.                 }
  1329.  
  1330.                 SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],2,ConvNumber,FileTransferInfo -> TotalSize);
  1331.  
  1332.                 if(FileTransferInfo -> TotalFiles)
  1333.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],4,LocaleString(MSG_TRANSFERPANEL_NUMBER_TO_GO_PERCENT_TXT),FileTransferInfo -> DoneFiles,FileTransferInfo -> TotalFiles,(100 * FileTransferInfo -> DoneFiles) / FileTransferInfo -> TotalFiles);
  1334.                 else
  1335.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],4,LocaleString(MSG_TRANSFERPANEL_NUMBER_TO_GO_PERCENT_TXT),FileTransferInfo -> DoneFiles,FileTransferInfo -> TotalFiles,0);
  1336.             }
  1337.         }
  1338.  
  1339.         if((UpdateInfo -> xpru_updatemask & XPRU_FILESIZE) && UpdateInfo -> xpru_filesize != -1)
  1340.         {
  1341.             if(CurrentFile)
  1342.             {
  1343.                 if(CurrentFile -> DirLock)
  1344.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber10,UpdateInfo -> xpru_filesize);
  1345.                 else
  1346.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber,UpdateInfo -> xpru_filesize);
  1347.             }
  1348.             else
  1349.                 SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],0,ConvNumber,UpdateInfo -> xpru_filesize);
  1350.  
  1351.             if(ByteMax = UpdateInfo -> xpru_filesize)
  1352.                 NewByte = TRUE;
  1353.         }
  1354.  
  1355.         if((UpdateInfo -> xpru_updatemask & XPRU_BYTES) && UpdateInfo -> xpru_bytes != -1)
  1356.         {
  1357.             if(CurrentFile)
  1358.             {
  1359.                 if(CurrentFile -> DirLock)
  1360.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber10,ByteVal = UpdateInfo -> xpru_bytes);
  1361.                 else
  1362.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
  1363.             }
  1364.             else
  1365.                 SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],1,ConvNumber,ByteVal = UpdateInfo -> xpru_bytes);
  1366.  
  1367.             if(FileTransferInfo)
  1368.             {
  1369.                 ULONG Len = FileTransferInfo -> DoneSize + UpdateInfo -> xpru_bytes;
  1370.  
  1371.                 if(FileTransferInfo -> TotalSize)
  1372.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],3,LocaleString(MSG_TRANSFERPANEL_NUMBER_PERCENT_TXT),Len,(100 * Len) / FileTransferInfo -> TotalSize);
  1373.                 else
  1374.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],3,LocaleString(MSG_TRANSFERPANEL_NUMBER_PERCENT_TXT),Len,0);
  1375.             }
  1376.  
  1377.             if(ByteMax)
  1378.                 NewByte = TRUE;
  1379.  
  1380.             if(CurrentFile)
  1381.             {
  1382.                 if(CurrentFile -> DirLock && !Uploading)
  1383.                 {
  1384.                     if(CurrentFile -> InfoData . id_NumBlocks && CurrentFile -> InfoData . id_BytesPerBlock)
  1385.                     {
  1386.                         if(ByteMax)
  1387.                         {
  1388.                             register LONG Space = CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed;
  1389.  
  1390.                             if(Space >= 0)
  1391.                             {
  1392.                                 register LONG Blocks = CalculateBlocks(ByteMax,CurrentFile -> InfoData . id_BytesPerBlock);
  1393.  
  1394.                                 if(Space < Blocks)
  1395.                                 {
  1396.                                     if(!Alerted)
  1397.                                     {
  1398.                                         Alerted = TRUE;
  1399.  
  1400.                                         Say(LocaleString(MSG_TERMXPR_SAY_FILE_MAY_NOT_FIT_TXT));
  1401.                                     }
  1402.  
  1403.                                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,LocaleString(MSG_TERMXPR_FILE_MAY_NOT_FIT_TXT));
  1404.                                 }
  1405.                                 else
  1406.                                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),Space * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks,"");
  1407.                             }
  1408.                             else
  1409.                                 SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
  1410.                         }
  1411.                         else
  1412.                             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],2,LocaleString(MSG_TERMXPR_BYTES_FULL_TXT),(CurrentFile -> InfoData . id_NumBlocks - CurrentFile -> InfoData . id_NumBlocksUsed) * CurrentFile -> InfoData . id_BytesPerBlock,100 * (CurrentFile -> InfoData . id_NumBlocksUsed) / CurrentFile -> InfoData . id_NumBlocks);
  1413.                     }
  1414.                 }
  1415.             }
  1416.         }
  1417.  
  1418.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKS) && UpdateInfo -> xpru_blocks != -1)
  1419.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT1],5,ConvNumber,UpdateInfo -> xpru_blocks);
  1420.  
  1421.  
  1422.         if((UpdateInfo -> xpru_updatemask & XPRU_DATARATE) && UpdateInfo -> xpru_datarate > 0)
  1423.         {
  1424.             register LONG Change;
  1425.  
  1426.             CPS_Current = UpdateInfo -> xpru_datarate;
  1427.  
  1428.             if(CPS_Last)
  1429.             {
  1430.                 if(CPS_Last < UpdateInfo -> xpru_datarate)
  1431.                     Change = (100 * (UpdateInfo -> xpru_datarate - CPS_Last)) / CPS_Last;
  1432.                 else
  1433.                     Change = (100 * (CPS_Last - UpdateInfo -> xpru_datarate)) / CPS_Last;
  1434.             }
  1435.             else
  1436.                 Change = 100;
  1437.  
  1438.             if(Change > 1)
  1439.             {
  1440.                 SZ_PrintLine(TransferWindow -> RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],0,ConvNumber,UpdateInfo -> xpru_datarate);
  1441.  
  1442.                 CPS_Last = UpdateInfo -> xpru_datarate;
  1443.             }
  1444.  
  1445.             if(UpdateInfo -> xpru_datarate < CPS_Minimum)
  1446.                 CPS_Minimum = UpdateInfo -> xpru_datarate;
  1447.  
  1448.             if(UpdateInfo -> xpru_datarate > CPS_Maximum)
  1449.                 CPS_Maximum = UpdateInfo -> xpru_datarate;
  1450.  
  1451.             if((ULONG)(CPS_Average + UpdateInfo -> xpru_datarate) >= CPS_Average)
  1452.             {
  1453.                 CPS_Average += UpdateInfo -> xpru_datarate;
  1454.  
  1455.                 CPS_Count++;
  1456.             }
  1457.         }
  1458.  
  1459.         if((UpdateInfo -> xpru_updatemask & XPRU_CHARDELAY) && UpdateInfo -> xpru_chardelay != -1)
  1460.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],1,ConvNumber,UpdateInfo -> xpru_chardelay);
  1461.  
  1462.         if((UpdateInfo -> xpru_updatemask & XPRU_PACKETDELAY) && UpdateInfo -> xpru_packetdelay != -1)
  1463.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],2,ConvNumber,UpdateInfo -> xpru_packetdelay);
  1464.  
  1465.         if((UpdateInfo -> xpru_updatemask & XPRU_PACKETTYPE) && UpdateInfo -> xpru_packettype != -1)
  1466.         {
  1467.             if(UpdateInfo -> xpru_packettype > 32 && UpdateInfo -> xpru_packettype < 256)
  1468.             {
  1469.                 if(IsPrintable[UpdateInfo -> xpru_packettype])
  1470.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,"`%lc'",UpdateInfo -> xpru_packettype);
  1471.                 else
  1472.                     SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
  1473.             }
  1474.             else
  1475.                 SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],3,ConvNumber,UpdateInfo -> xpru_packettype);
  1476.         }
  1477.  
  1478.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKCHECK) && UpdateInfo -> xpru_blockcheck)
  1479.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],4,UpdateInfo -> xpru_blockcheck);
  1480.  
  1481.         if((UpdateInfo -> xpru_updatemask & XPRU_BLOCKSIZE) && UpdateInfo -> xpru_blocksize != -1)
  1482.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT1],5,ConvNumber,UpdateInfo -> xpru_blocksize);
  1483.  
  1484.  
  1485.         if((UpdateInfo -> xpru_updatemask & XPRU_EXPECTTIME) && UpdateInfo -> xpru_expecttime)
  1486.         {
  1487.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],0,UpdateInfo -> xpru_expecttime);
  1488.  
  1489.             if(TimeMax = GetSeconds((STRPTR)UpdateInfo -> xpru_expecttime))
  1490.                 NewTime = TRUE;
  1491.         }
  1492.  
  1493.         if((UpdateInfo -> xpru_updatemask & XPRU_ELAPSEDTIME) && UpdateInfo -> xpru_elapsedtime)
  1494.         {
  1495.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_LEFT2],1,UpdateInfo -> xpru_elapsedtime);
  1496.  
  1497.             TimeVal = GetSeconds((STRPTR)UpdateInfo -> xpru_elapsedtime);
  1498.  
  1499.             if(TimeMax)
  1500.                 NewTime = TRUE;
  1501.         }
  1502.  
  1503.         if((UpdateInfo -> xpru_updatemask & XPRU_ERRORS) && UpdateInfo -> xpru_errors != -1)
  1504.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],0,ConvNumber,UpdateInfo -> xpru_errors);
  1505.  
  1506.         if((UpdateInfo -> xpru_updatemask & XPRU_TIMEOUTS) && UpdateInfo -> xpru_timeouts != -1)
  1507.             SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_RIGHT2],1,ConvNumber,UpdateInfo -> xpru_timeouts);
  1508.  
  1509.         if(NewByte)
  1510.         {
  1511.             LONG Percent;
  1512.  
  1513.             if(ByteMax)
  1514.                 Percent = (100 * ByteVal) / ByteMax;
  1515.             else
  1516.                 Percent = 0;
  1517.  
  1518.             if(Percent != LastPercent)
  1519.             {
  1520.                 LastPercent = Percent;
  1521.  
  1522.                 ShowStats(TransferGadgetArray[GAD_TRANSFER_PERCENT],ByteVal,ByteMax);
  1523.                 ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",Percent);
  1524.             }
  1525.         }
  1526.  
  1527.         if(NewTime)
  1528.         {
  1529.             register LONG TimeDif,Change;
  1530.  
  1531.             if(TimeVal > TimeMax)
  1532.                 TimeDif = 0;
  1533.             else
  1534.                 TimeDif = TimeMax - TimeVal;
  1535.  
  1536.             if(LastTimeDif)
  1537.             {
  1538.                 if(LastTimeDif < TimeDif)
  1539.                     Change = (100 * (TimeDif - LastTimeDif)) / LastTimeDif;
  1540.                 else
  1541.                     Change = (100 * (LastTimeDif - TimeDif)) / LastTimeDif;
  1542.             }
  1543.             else
  1544.                 Change = 100;
  1545.  
  1546.                 /* Don't update the display unless the change
  1547.                  * exceeds 2% of the previous value.
  1548.                  */
  1549.  
  1550.             if(Change > 2)
  1551.             {
  1552.                 UBYTE        TimeBuffer[20],
  1553.                         DateBuffer[20];
  1554.                 struct DateTime    DateTime;
  1555.  
  1556.                 LastTimeDif = TimeDif;
  1557.  
  1558.                 ShowStats(TransferGadgetArray[GAD_TRANSFER_TIME],TimeDif,TimeMax);
  1559.                 ShowString(TransferGadgetArray[GAD_TRANSFER_TIME],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
  1560.  
  1561.                     /* A rapidly changing transfer time display would
  1562.                      * cause the transfer completion time display to
  1563.                      * change at the same pace. As the completion time
  1564.                      * display calculation is rather costly, a change smaller
  1565.                      * than 5% of the previous value is silently ignored.
  1566.                      */
  1567.  
  1568.                 if(Change > 5)
  1569.                 {
  1570.                         /* Obtain current time. */
  1571.  
  1572.                     DateStamp(&DateTime . dat_Stamp);
  1573.  
  1574.                         /* Add the time to go. */
  1575.  
  1576.                     DateTime . dat_Stamp . ds_Tick        += (TimeDif % 60) * TICKS_PER_SECOND;
  1577.                     DateTime . dat_Stamp . ds_Minute    += TimeDif / 60 + DateTime . dat_Stamp . ds_Tick / (60 * TICKS_PER_SECOND);
  1578.                     DateTime . dat_Stamp . ds_Days        += DateTime . dat_Stamp . ds_Minute / 1440;
  1579.  
  1580.                     DateTime . dat_Stamp . ds_Tick        %= 60 * TICKS_PER_SECOND;
  1581.                     DateTime . dat_Stamp . ds_Minute    %= 1440;
  1582.  
  1583.                         /* Convert it to human readable form. */
  1584.  
  1585.                     DateTime . dat_Format    = FORMAT_DOS;
  1586.                     DateTime . dat_Flags    = DTF_SUBST;
  1587.                     DateTime . dat_StrDay    = NULL;
  1588.                     DateTime . dat_StrDate    = DateBuffer;
  1589.                     DateTime . dat_StrTime    = TimeBuffer;
  1590.  
  1591.                         /* Conversion succeeded? */
  1592.  
  1593.                     if(DateToStr(&DateTime))
  1594.                         SZ_PrintLine(RPort,TransferBoxArray[BOX_TRANSFER_2],3,"%s %s",DateBuffer,TimeBuffer);
  1595.                 }
  1596.             }
  1597.         }
  1598.     }
  1599.  
  1600.     if(TransferPerfWindow)
  1601.     {
  1602.         struct RastPort *RPort = TransferPerfWindow -> RPort;
  1603.         LONG Height,Left,Top,Min,Avg,Cur;
  1604.  
  1605.         Left = TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1);
  1606.         Height = TransferPerfWindow -> Height - (TransferPerfWindow -> BorderTop + TransferPerfWindow -> BorderBottom + 1);
  1607.         Top = TransferPerfWindow -> BorderTop + Height;
  1608.  
  1609.         if(CPS_Maximum && CPS_Maximum != ~0)
  1610.         {
  1611.             Min = (Height * CPS_Minimum) / CPS_Maximum;
  1612.             Cur = (Height * CPS_Current) / CPS_Maximum;
  1613.  
  1614.             if(CPS_Count)
  1615.                 Avg = ((CPS_Average / CPS_Count) * Height) / CPS_Maximum;
  1616.             else
  1617.                 Avg = 0;
  1618.         }
  1619.         else
  1620.             Min = Avg = Cur = 0;
  1621.  
  1622.         if(CPL_Min == -1)
  1623.             CPL_Min = Min;
  1624.  
  1625.         if(CPL_Avg == -1)
  1626.             CPL_Avg = Avg;
  1627.  
  1628.         if(CPL_Cur == -1)
  1629.             CPL_Cur = Cur;
  1630.  
  1631.         ScrollRaster(RPort,1,0,TransferPerfWindow -> BorderLeft,TransferPerfWindow -> BorderTop,TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1),TransferPerfWindow -> Height - (TransferPerfWindow -> BorderBottom + 1));
  1632.  
  1633.         if(CPL_Cur != -1 && Cur != -1)
  1634.         {
  1635.             SetAPen(RPort,DrawInfo -> dri_Pens[SHADOWPEN]);
  1636.             Move(RPort,Left,Top - CPL_Cur);
  1637.             Draw(RPort,Left,Top - Cur);
  1638.         }
  1639.  
  1640.         if(CPL_Min != -1 && Min != -1)
  1641.         {
  1642.             SetAPen(RPort,DrawInfo -> dri_Pens[HIGHLIGHTTEXTPEN]);
  1643.             Move(RPort,Left,Top - CPL_Min);
  1644.             Draw(RPort,Left,Top - Min);
  1645.         }
  1646.  
  1647.         if(CPL_Avg != -1 && Avg != -1)
  1648.         {
  1649.             SetAPen(RPort,DrawInfo -> dri_Pens[FILLPEN]);
  1650.             Move(RPort,Left,Top - CPL_Avg);
  1651.             Draw(RPort,Left,Top - Avg);
  1652.         }
  1653.  
  1654.         CPL_Min = Min;
  1655.         CPL_Avg = Avg;
  1656.         CPL_Cur = Cur;
  1657.     }
  1658.  
  1659.     return(1);
  1660. }
  1661.  
  1662.     /* xpr_chkabort():
  1663.      *
  1664.      *    Check if the user has aborted the transfer.
  1665.      */
  1666.  
  1667. LONG __saveds __asm
  1668. xpr_chkabort()
  1669. {
  1670.     struct IntuiMessage    *Massage;
  1671.     struct Window        *IWindow;
  1672.     ULONG             IClass,
  1673.                  Code;
  1674.     struct Gadget        *Gadget;
  1675.     LONG             Result = 0;
  1676.  
  1677.         /* No window available for output? */
  1678.  
  1679.     if(!TransferWindow)
  1680.     {
  1681.         if(!OpenTransferWindow())
  1682.             return(-1);
  1683.     }
  1684.  
  1685.         /* Are we to check the carrier status? */
  1686.  
  1687.     if(Config -> SerialConfig -> CheckCarrier)
  1688.     {
  1689.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1690.  
  1691.         DoIO(WriteRequest);
  1692.  
  1693.             /* Return error if carrier is lost. */
  1694.  
  1695.         if(WriteRequest -> io_Status & CIAF_COMCD)
  1696.         {
  1697.             if(!CarrierMessage)
  1698.             {
  1699.                 CarrierMessage = TRUE;
  1700.  
  1701.                 AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
  1702.             }
  1703.  
  1704.             Online = FALSE;
  1705.  
  1706.             TransferError = TRUE;
  1707.  
  1708.             return(-1);
  1709.         }
  1710.     }
  1711.  
  1712.         /* Process all incoming messages. */
  1713.  
  1714.     while(Massage = (struct IntuiMessage *)GT_GetIMsg(TransferWindow -> UserPort))
  1715.     {
  1716.         IClass    = Massage -> Class;
  1717.         Code    = Massage -> Code;
  1718.         Gadget    = (struct Gadget *)Massage -> IAddress;
  1719.         IWindow    = Massage -> IDCMPWindow;
  1720.  
  1721.         GT_ReplyIMsg(Massage);
  1722.  
  1723.         if(IWindow == TransferWindow)
  1724.         {
  1725.             KeySelect(TransferGadgetArray,4,Code,TransferWindow,&Gadget,&IClass,&Code);
  1726.  
  1727.             if(!Result)
  1728.             {
  1729.                 if(IClass == IDCMP_NEWSIZE)
  1730.                 {
  1731.                     if(!(TransferWindow -> Flags & WFLG_ZOOMED))
  1732.                     {
  1733.                         LONG TimeDif = (TimeMax - TimeVal) < 0 ? 0 : TimeMax - TimeVal;
  1734.  
  1735.                         RefreshTransferWindow();
  1736.  
  1737.                         ShowStats(TransferGadgetArray[GAD_TRANSFER_PERCENT],ByteVal,ByteMax);
  1738.  
  1739.                         if(ByteMax)
  1740.                             ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",(100 * ByteVal) / ByteMax);
  1741.                         else
  1742.                             ShowString(TransferGadgetArray[GAD_TRANSFER_PERCENT],"%ld%%",0);
  1743.  
  1744.                         ShowStats(TransferGadgetArray[GAD_TRANSFER_TIME],TimeDif,TimeMax);
  1745.  
  1746.                         ShowString(TransferGadgetArray[GAD_TRANSFER_TIME],"%2ld:%02ld:%02ld",TimeDif / 3600,(TimeDif / 60) % 60,TimeDif % 60);
  1747.                     }
  1748.                 }
  1749.  
  1750.                 if(IClass == IDCMP_CLOSEWINDOW)
  1751.                 {
  1752.                     LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
  1753.  
  1754.                     TransferAborted = TRUE;
  1755.  
  1756.                     Result = -1;
  1757.                 }
  1758.  
  1759.                 if(IClass == IDCMP_GADGETUP)
  1760.                 {
  1761.                     switch(Gadget -> GadgetID)
  1762.                     {
  1763.                         case GAD_TRANSFER_ABORT:
  1764.  
  1765.                             LogAction(LocaleString(MSG_TERMXPR_LOGMSG_TRANSFER_ABORTED_TXT));
  1766.  
  1767.                             TransferAborted = TRUE;
  1768.  
  1769.                             Result = -1;
  1770.  
  1771.                             break;
  1772.  
  1773.                         case GAD_TRANSFER_SKIP:
  1774.  
  1775.                             LogAction(LocaleString(MSG_TERMXPR_LOGMSG_FILE_SKIPPED_TXT));
  1776.  
  1777.                             Result = 1;
  1778.  
  1779.                             break;
  1780.                     }
  1781.                 }
  1782.             }
  1783.         }
  1784.         else
  1785.         {
  1786.             if(TransferPerfWindow)
  1787.             {
  1788.                 struct RastPort *RPort = TransferPerfWindow -> RPort;
  1789.  
  1790.                 if(IClass == IDCMP_NEWSIZE)
  1791.                 {
  1792.                     SetAPen(RPort,0);
  1793.  
  1794.                     RectFill(RPort,TransferPerfWindow -> BorderLeft,TransferPerfWindow -> BorderTop,TransferPerfWindow -> Width - (TransferPerfWindow -> BorderRight + 1),TransferPerfWindow -> Height - (TransferPerfWindow -> BorderBottom + 1));
  1795.  
  1796.                     CPL_Min = CPL_Avg = CPL_Cur = -1;
  1797.                 }
  1798.  
  1799.                 if(IClass == IDCMP_CLOSEWINDOW)
  1800.                 {
  1801.                     PutWindowInfo(WINDOW_PERF,TransferPerfWindow -> LeftEdge,TransferPerfWindow -> TopEdge,TransferPerfWindow -> Width,TransferPerfWindow -> Height);
  1802.  
  1803.                     CloseWindowSafely(TransferPerfWindow);
  1804.  
  1805.                     TransferPerfWindow = NULL;
  1806.                 }
  1807.             }
  1808.         }
  1809.     }
  1810.  
  1811.     return(Result);
  1812. }
  1813.  
  1814.     /* CreateAllGetsGadgets():
  1815.      *
  1816.      *    Create all the gadgets required by xpr_gets() and the like.
  1817.      */
  1818.  
  1819. struct Gadget *
  1820. CreateAllGetsGadgets(BYTE LoadGadget,BYTE Password,WORD MaxChars,STRPTR String,STRPTR Prompt,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,struct Screen *Screen)
  1821. {
  1822.     struct Gadget        *Gadget;
  1823.     struct NewGadget     NewGadget;
  1824.  
  1825.     if(MaxChars < 1)
  1826.         MaxChars = 255;
  1827.  
  1828.     memset(&NewGadget,0,sizeof(struct NewGadget));
  1829.  
  1830.     SZ_SizeSetup(Screen,&UserFont,TRUE);
  1831.  
  1832.     if(Gadget = CreateContext(GadgetList))
  1833.     {
  1834.         WORD Width = SZ_TextWidth(Prompt),Counter = 0;
  1835.  
  1836.         if(Width < SZ_Width(STRING_KIND,NULL,60,NULL))
  1837.             Width = SZ_Width(STRING_KIND,NULL,60,NULL);
  1838.  
  1839.         SZ_SetWidth(Width);
  1840.  
  1841.         NewGadget . ng_GadgetText    = Prompt;
  1842.         NewGadget . ng_TextAttr        = &UserFont;
  1843.         NewGadget . ng_VisualInfo    = VisualInfo;
  1844.         NewGadget . ng_GadgetID        = Counter;
  1845.         NewGadget . ng_Flags        = PLACETEXT_ABOVE;
  1846.  
  1847.         if(LoadGadget)
  1848.         {
  1849.             GadgetArray[Counter++] = Gadget = CreateGadget(Password ? PASSWORD_KIND : STRING_KIND,Gadget,&NewGadget,
  1850.                 SZ_Adjust,    TRUE,
  1851.                 SZ_AutoWidth,    TRUE,
  1852.                 SZ_LeaveFolder,    TRUE,
  1853.  
  1854.                 GTST_MaxChars,    MaxChars,
  1855.                 GTST_String,    String,
  1856.                 GA_TabCycle,    FALSE,
  1857.             TAG_DONE);
  1858.  
  1859.             NewGadget . ng_GadgetID = Counter;
  1860.  
  1861.             GadgetArray[Counter++] = Gadget = CreateGadget(FILE_KIND,Gadget,&NewGadget,
  1862.                 SZ_Adjust,    TRUE,
  1863.                 SZ_AutoWidth,    TRUE,
  1864.                 SZ_PlaceLeft,    TRUE,
  1865.             TAG_DONE);
  1866.         }
  1867.         else
  1868.         {
  1869.             GadgetArray[Counter++] = Gadget = CreateGadget(Password ? PASSWORD_KIND : STRING_KIND,Gadget,&NewGadget,
  1870.                 SZ_Adjust,    TRUE,
  1871.                 SZ_AutoWidth,    TRUE,
  1872.  
  1873.                 GTST_MaxChars,    MaxChars,
  1874.                 GTST_String,    String,
  1875.                 GA_TabCycle,    FALSE,
  1876.             TAG_DONE);
  1877.  
  1878.             GadgetArray[Counter++] = NULL;
  1879.         }
  1880.  
  1881.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_TERMXPR_OKAY_GAD),0,NULL);
  1882.         SZ_UpdateMaxWidth(BUTTON_KIND,LocaleString(MSG_GLOBAL_CANCEL_GAD),0,NULL);
  1883.  
  1884.         SZ_SetWidth(SZ_ResetMaxWidth());
  1885.  
  1886.         NewGadget . ng_GadgetText    = LocaleString(MSG_TERMXPR_OKAY_GAD);
  1887.         NewGadget . ng_GadgetID        = Counter;
  1888.         NewGadget . ng_Flags        = 0;
  1889.  
  1890.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1891.             SZ_Adjust,    TRUE,
  1892.             SZ_AutoWidth,    TRUE,
  1893.             SZ_AlignExtra,    TRUE,
  1894.             SZ_AlignLeft,    TRUE,
  1895.             SZ_AlignBottom,    TRUE,
  1896.  
  1897.             GT_Underscore,    '_',
  1898.         TAG_DONE);
  1899.  
  1900.         NewGadget . ng_GadgetText    = LocaleString(MSG_GLOBAL_CANCEL_GAD);
  1901.         NewGadget . ng_GadgetID        = Counter;
  1902.  
  1903.         GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1904.             SZ_Adjust,    TRUE,
  1905.             SZ_AutoWidth,    TRUE,
  1906.             SZ_AlignRight,    TRUE,
  1907.  
  1908.             GT_Underscore,    '_',
  1909.         TAG_DONE);
  1910.     }
  1911.  
  1912.     return(Gadget);
  1913. }
  1914.  
  1915.     /* xpr_gets(STRPTR Prompt,STRPTR Buffer):
  1916.      *
  1917.      *    Prompt the user for string input.
  1918.      */
  1919.  
  1920. LONG __saveds __asm
  1921. xpr_gets(register __a0 STRPTR Prompt,register __a1 STRPTR Buffer)
  1922. {
  1923.     struct Gadget    *GadgetList = NULL;
  1924.     struct Gadget    *GadgetArray[4];
  1925.     struct Window    *PanelWindow;
  1926.     LONG         Success = FALSE;
  1927.  
  1928.     if(!Prompt)
  1929.         Prompt = LocaleString(MSG_TERMXPR_INPUT_REQUIRED_TXT);
  1930.  
  1931.     if(CreateAllGetsGadgets(FALSE,FALSE,0,Buffer,Prompt,GadgetArray,&GadgetList,VisualInfo,Window -> WScreen))
  1932.     {
  1933.         if(PanelWindow = OpenWindowTags(NULL,
  1934.             WA_Left,    GetScreenLeft(Window) + (GetScreenWidth(Window) - SZ_GetWindowWidth()) / 2,
  1935.             WA_Top,        GetScreenTop(Window) + (GetScreenHeight(Window) - SZ_GetWindowHeight())    / 2,
  1936.             WA_Width,    SZ_GetWindowWidth(),
  1937.             WA_Height,    SZ_GetWindowHeight(),
  1938.  
  1939.             WA_Activate,    TRUE,
  1940.             WA_DragBar,    TRUE,
  1941.             WA_DepthGadget,    TRUE,
  1942.             WA_CloseGadget,    TRUE,
  1943.             WA_RMBTrap,    TRUE,
  1944.             WA_CustomScreen,Window -> WScreen,
  1945.  
  1946.             WA_IDCMP,    IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_RAWKEY | BUTTONIDCMP | STRINGIDCMP,
  1947.  
  1948.             WA_Title,    LocaleString(MSG_GLOBAL_ENTER_TEXT_TXT),
  1949.         TAG_DONE))
  1950.         {
  1951.             struct IntuiMessage    *Massage;
  1952.             ULONG             IClass,Code,Qualifier;
  1953.             struct Gadget        *Gadget;
  1954.             BYTE             Terminated = FALSE;
  1955.  
  1956.             PushWindow(PanelWindow);
  1957.  
  1958.             AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  1959.             RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
  1960.             GT_RefreshWindow(PanelWindow,NULL);
  1961.  
  1962.             ActiveGadget = NULL;
  1963.  
  1964.             while(!Terminated)
  1965.             {
  1966.                 WaitPort(PanelWindow -> UserPort);
  1967.  
  1968.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
  1969.                 {
  1970.                     IClass        = Massage -> Class;
  1971.                     Code        = Massage -> Code;
  1972.                     Gadget        = (struct Gadget *)Massage -> IAddress;
  1973.                     Qualifier    = Massage -> Qualifier;
  1974.  
  1975.                     GT_ReplyIMsg(Massage);
  1976.  
  1977.                     if(IClass == IDCMP_VANILLAKEY)
  1978.                         KeySelect(GadgetArray,3,Code,PanelWindow,&Gadget,&IClass,&Code);
  1979.  
  1980.                     if(IClass == IDCMP_RAWKEY && Code == HELP_CODE)
  1981.                         DisplayBeep(PanelWindow -> WScreen);
  1982.  
  1983.                     if(IClass == IDCMP_GADGETDOWN)
  1984.                     {
  1985.                         if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
  1986.                             ActiveGadget = Gadget;
  1987.                     }
  1988.  
  1989.                     if(IClass == IDCMP_ACTIVEWINDOW && ActiveGadget)
  1990.                         ActivateGadget(ActiveGadget,PanelWindow,NULL);
  1991.  
  1992.                     if(IClass == IDCMP_CLOSEWINDOW)
  1993.                         Terminated = TRUE;
  1994.  
  1995.                     if(IClass == IDCMP_GADGETUP)
  1996.                     {
  1997.                         switch(Gadget -> GadgetID)
  1998.                         {
  1999.                             case 0:    if(!(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2000.                                 {
  2001.                                     strcpy(Buffer,SZ_GetString(GadgetArray[0]));
  2002.  
  2003.                                     Success = TRUE;
  2004.  
  2005.                                     Terminated = TRUE;
  2006.                                 }
  2007.  
  2008.                                 break;
  2009.  
  2010.                             case 2:    strcpy(Buffer,SZ_GetString(GadgetArray[0]));
  2011.  
  2012.                                 Success = TRUE;
  2013.  
  2014.                                 Terminated = TRUE;
  2015.  
  2016.                                 break;
  2017.  
  2018.                             case 3:    Terminated = TRUE;
  2019.  
  2020.                                 break;
  2021.                         }
  2022.                     }
  2023.                 }
  2024.             }
  2025.  
  2026.             ActiveGadget = NULL;
  2027.  
  2028.             RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
  2029.  
  2030.             PopWindow();
  2031.  
  2032.             CloseWindow(PanelWindow);
  2033.         }
  2034.  
  2035.         FreeGadgets(GadgetList);
  2036.     }
  2037.  
  2038.     return(Success);
  2039. }
  2040.  
  2041.     /* xpr_setserial(LONG Status):
  2042.      *
  2043.      *    Set/read the serial status (parameters).
  2044.      */
  2045.  
  2046. LONG __saveds __asm
  2047. xpr_setserial(register __d0 LONG Status)
  2048. {
  2049.     if(WriteRequest)
  2050.     {
  2051.         STATIC LONG XprBauds[12] =
  2052.         {
  2053.                110,
  2054.                300,
  2055.               1200,
  2056.               2400,
  2057.               4800,
  2058.               9600,
  2059.              19200,
  2060.              31250,
  2061.              38400,
  2062.              57600,
  2063.              76800,
  2064.             115200
  2065.         };
  2066.  
  2067.         LONG Return,i;
  2068.  
  2069.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  2070.  
  2071.         DoIO(WriteRequest);
  2072.  
  2073.         Return = WriteRequest -> io_SerFlags & 0xFF;
  2074.  
  2075.         if(WriteRequest -> io_ExtFlags & SEXTF_MSPON)
  2076.             Return |= ST_PARTYMARKON;
  2077.  
  2078.         if(WriteRequest -> io_ExtFlags & SEXTF_MARK)
  2079.             Return |= ST_PARTYMARK;
  2080.  
  2081.         if(WriteRequest -> io_StopBits == 2)
  2082.             Return |= ST_2BITS;
  2083.  
  2084.         if(WriteRequest -> io_ReadLen == 7)
  2085.             Return |= ST_READ7;
  2086.  
  2087.         if(WriteRequest -> io_WriteLen == 7)
  2088.             Return |= ST_WRITE7;
  2089.  
  2090.         for(i = 0 ; i < 12 ; i++)
  2091.         {
  2092.             if(XprBauds[i] >= WriteRequest -> io_Baud)
  2093.             {
  2094.                 Return |= (i << 16);
  2095.  
  2096.                 break;
  2097.             }
  2098.         }
  2099.  
  2100.             /* Update serial parameters, don't change
  2101.              * the baud rate however.
  2102.              */
  2103.  
  2104.         if(Status != -1)
  2105.         {
  2106.             WriteRequest -> io_SerFlags = Status & 0xFF;
  2107.             WriteRequest -> io_ExtFlags = 0;
  2108.  
  2109.             if(Status & ST_PARTYMARKON)
  2110.                 WriteRequest -> io_ExtFlags |= SEXTF_MSPON;
  2111.  
  2112.             if(Status & ST_PARTYMARK)
  2113.                 WriteRequest -> io_ExtFlags |= SEXTF_MARK;
  2114.  
  2115.             if(Status & ST_2BITS)
  2116.                 WriteRequest -> io_StopBits = 2;
  2117.             else
  2118.                 WriteRequest -> io_StopBits = 1;
  2119.  
  2120.             if(Status & ST_READ7)
  2121.                 WriteRequest -> io_ReadLen = 7;
  2122.             else
  2123.                 WriteRequest -> io_ReadLen = 8;
  2124.  
  2125.             if(Status & ST_WRITE7)
  2126.                 WriteRequest -> io_WriteLen = 7;
  2127.             else
  2128.                 WriteRequest -> io_WriteLen = 8;
  2129.  
  2130.             ReadRequest -> io_Baud        = WriteRequest -> io_Baud;
  2131.             ReadRequest -> io_SerFlags    = WriteRequest -> io_SerFlags;
  2132.             ReadRequest -> io_ExtFlags    = WriteRequest -> io_ExtFlags;
  2133.             ReadRequest -> io_StopBits    = WriteRequest -> io_StopBits;
  2134.             ReadRequest -> io_ReadLen    = WriteRequest -> io_ReadLen;
  2135.             ReadRequest -> io_WriteLen    = WriteRequest -> io_WriteLen;
  2136.  
  2137.             WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  2138.  
  2139.             DoIO(WriteRequest);
  2140.  
  2141.             ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  2142.  
  2143.             DoIO(ReadRequest);
  2144.  
  2145.             GetFlags(Config,WriteRequest);
  2146.         }
  2147.  
  2148.         return(Return);
  2149.     }
  2150.     else
  2151.         return(-1);
  2152. }
  2153.  
  2154.     /* xpr_ffirst(STRPTR Buffer,STRPTR Pattern):
  2155.      *
  2156.      *    Batch file upload: find the first matching file and return
  2157.      *    its name.
  2158.      */
  2159.  
  2160. LONG __saveds __asm
  2161. xpr_ffirst(register __a0 STRPTR Buffer,register __a1 STRPTR Pattern)
  2162. {
  2163.     if(FileTransferInfo)
  2164.     {
  2165.         FileTransferInfo -> DoneSize    = 0;
  2166.         FileTransferInfo -> DoneFiles    = 0;
  2167.  
  2168.         FileTransferInfo -> CurrentFile    = (struct FileTransferNode *)FileTransferInfo -> FileList . mlh_Head;
  2169.         FileTransferInfo -> CurrentSize    = FileTransferInfo -> CurrentFile -> Size;
  2170.  
  2171.         strcpy(Buffer,FileTransferInfo -> CurrentFile -> Name);
  2172.  
  2173.         return(1);
  2174.     }
  2175.     else
  2176.         return(0);
  2177. }
  2178.  
  2179.     /* xpr_fnext(LONG OldState,STRPTR Buffer,STRPTR Pattern):
  2180.      *
  2181.      *    Batch file upload: find the next matching file
  2182.      *    - if any - and return its name.
  2183.      */
  2184.  
  2185. LONG __saveds __asm
  2186. xpr_fnext(register __d0 LONG OldState,register __a0 STRPTR Buffer,register __a1 STRPTR Pattern)
  2187. {
  2188.     if(FileTransferInfo)
  2189.     {
  2190.         if(FileTransferInfo -> CurrentFile -> Node . mln_Succ -> mln_Succ)
  2191.         {
  2192.             FileTransferInfo -> DoneSize    += FileTransferInfo -> CurrentSize;
  2193.             FileTransferInfo -> DoneFiles    += 1;
  2194.  
  2195.             FileTransferInfo -> CurrentFile  = (struct FileTransferNode *)FileTransferInfo -> CurrentFile -> Node . mln_Succ;
  2196.             FileTransferInfo -> CurrentSize  = FileTransferInfo -> CurrentFile -> Size;
  2197.  
  2198.             strcpy(Buffer,FileTransferInfo -> CurrentFile -> Name);
  2199.  
  2200.             return(1);
  2201.         }
  2202.     }
  2203.  
  2204.     return(0);
  2205. }
  2206.  
  2207.     /* xpr_finfo(STRPTR FileName,LONG InfoType):
  2208.      *
  2209.      *    Return information on a given file.
  2210.      */
  2211.  
  2212. LONG __saveds __asm
  2213. xpr_finfo(register __a0 STRPTR FileName,register __d0 LONG InfoType)
  2214. {
  2215.     struct FileInfoBlock    *FileInfo;
  2216.     LONG             Size;
  2217.  
  2218.     switch(InfoType)
  2219.     {
  2220.             /* Return the file size. */
  2221.  
  2222.         case 1:    Size = 0;
  2223.  
  2224.             if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  2225.             {
  2226.                 UBYTE    RealName[MAX_FILENAME_LENGTH];
  2227.                 BPTR    FileLock;
  2228.  
  2229.                 FileName = NewFileName(FileName,RealName);
  2230.  
  2231.                 if(FileLock = Lock(FileName,ACCESS_READ))
  2232.                 {
  2233.                     if(Examine(FileLock,FileInfo))
  2234.                     {
  2235.                         if(FileInfo -> fib_DirEntryType < 0)
  2236.                             Size = FileInfo -> fib_Size;
  2237.                     }
  2238.  
  2239.                     UnLock(FileLock);
  2240.                 }
  2241.  
  2242.                 FreeDosObject(DOS_FIB,FileInfo);
  2243.             }
  2244.  
  2245.             return(Size);
  2246.  
  2247.             /* Return the file transfer mode. */
  2248.  
  2249.         case 2:    return(BinaryTransfer ? 1 : 2);
  2250.  
  2251.             /* Ignore the rest. */
  2252.  
  2253.         default:return(0);
  2254.     }
  2255. }
  2256.  
  2257.     /* xpr_options(LONG NumOpts,struct xpr_option **Opts):
  2258.      *
  2259.      *    Provide a more polished user interface to set the
  2260.      *    transfer protocol options.
  2261.      */
  2262.  
  2263. ULONG __saveds __asm
  2264. xpr_options(register __d0 LONG NumOpts,register __a0 struct xpr_option **Opts)
  2265. {
  2266.     struct Gadget    *GadgetList = NULL;
  2267.     struct Gadget    *GadgetArray[34];
  2268.     struct Window    *PanelWindow;
  2269.     LONG         i,Count;
  2270.  
  2271.     ULONG         Flags = 0;
  2272.  
  2273.         /* We only have 32 bits! */
  2274.  
  2275.     if(NumOpts > 32)
  2276.         NumOpts = 32;
  2277.  
  2278.     if(CreateAllOptionGadgets(&Count,NumOpts,Opts,GadgetArray,&GadgetList,VisualInfo))
  2279.     {
  2280.         if(PanelWindow = OpenWindowTags(NULL,
  2281.             WA_Left,    GetScreenLeft(Window) + (GetScreenWidth(Window) - SZ_GetWindowWidth()) / 2,
  2282.             WA_Top,        GetScreenTop(Window) + (GetScreenHeight(Window) - SZ_GetWindowHeight())    / 2,
  2283.             WA_Width,    SZ_GetWindowWidth(),
  2284.             WA_Height,    SZ_GetWindowHeight(),
  2285.  
  2286.             WA_Activate,    TRUE,
  2287.             WA_DragBar,    TRUE,
  2288.             WA_DepthGadget,    TRUE,
  2289.             WA_CloseGadget,    TRUE,
  2290.             WA_RMBTrap,    TRUE,
  2291.             WA_CustomScreen,Window -> WScreen,
  2292.  
  2293.             WA_IDCMP,    IDCMP_GADGETDOWN | IDCMP_ACTIVEWINDOW | IDCMP_CLOSEWINDOW | IDCMP_RAWKEY | IDCMP_VANILLAKEY | CHECKBOXIDCMP | STRINGIDCMP | INTEGERIDCMP | BUTTONIDCMP,
  2294.  
  2295.             WA_Title,    OptionTitle ? OptionTitle : LocaleString(MSG_TERMXPR_TRANSFER_OPTIONS_TXT),
  2296.         TAG_DONE))
  2297.         {
  2298.             struct IntuiMessage    *Massage;
  2299.             ULONG             IClass,Code;
  2300.             struct Gadget        *Gadget;
  2301.             BYTE             Terminated = FALSE,
  2302.                          CheckFlags = FALSE;
  2303.  
  2304.             PushWindow(PanelWindow);
  2305.  
  2306.             AddGList(PanelWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2307.             RefreshGList(GadgetList,PanelWindow,NULL,(UWORD)-1);
  2308.             GT_RefreshWindow(PanelWindow,NULL);
  2309.  
  2310.             ActiveGadget = NULL;
  2311.  
  2312.             ClrSignal(SIG_BREAK);
  2313.  
  2314.             while(!Terminated)
  2315.             {
  2316.                 if(Wait(PORTMASK(PanelWindow -> UserPort) | SIG_BREAK) & SIG_BREAK)
  2317.                     break;
  2318.  
  2319.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(PanelWindow -> UserPort)))
  2320.                 {
  2321.                     IClass    = Massage -> Class;
  2322.                     Code    = Massage -> Code;
  2323.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2324.  
  2325.                     GT_ReplyIMsg(Massage);
  2326.  
  2327.                     if(IClass == IDCMP_VANILLAKEY)
  2328.                         KeySelect(GadgetArray,Count,Code,PanelWindow,&Gadget,&IClass,&Code);
  2329.  
  2330.                     if(IClass == IDCMP_RAWKEY && Code == HELP_CODE)
  2331.                         DisplayBeep(PanelWindow -> WScreen);
  2332.  
  2333.                     if(IClass == IDCMP_GADGETDOWN)
  2334.                     {
  2335.                         if((Gadget -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
  2336.                             ActiveGadget = Gadget;
  2337.                     }
  2338.  
  2339.                     if(IClass == IDCMP_ACTIVEWINDOW && ActiveGadget)
  2340.                         ActivateGadget(ActiveGadget,PanelWindow,NULL);
  2341.  
  2342.                     if(IClass == IDCMP_CLOSEWINDOW)
  2343.                         Terminated = TRUE;
  2344.  
  2345.                     if(IClass == IDCMP_GADGETUP)
  2346.                     {
  2347.                         switch(Gadget -> GadgetID)
  2348.                         {
  2349.                             case GAD_XPROPTIONS_USE:
  2350.  
  2351.                                 Terminated = CheckFlags = TRUE;
  2352.                                 break;
  2353.  
  2354.                             case GAD_XPROPTIONS_CANCEL:
  2355.  
  2356.                                 Terminated = TRUE;
  2357.                                 break;
  2358.  
  2359.                             default:
  2360.  
  2361.                                 if(Gadget -> GadgetID < NumOpts)
  2362.                                 {
  2363.                                     if(Opts[Gadget -> GadgetID] -> xpro_type == XPRO_COMMAND)
  2364.                                     {
  2365.                                         Flags |= (1 << Gadget -> GadgetID);
  2366.  
  2367.                                         Terminated = CheckFlags = TRUE;
  2368.                                     }
  2369.                                 }
  2370.  
  2371.                                 break;
  2372.                         }
  2373.                     }
  2374.                 }
  2375.             }
  2376.  
  2377.             if(CheckFlags)
  2378.             {
  2379.                 for(i = 0 ; i < NumOpts ; i++)
  2380.                 {
  2381.                     switch(Opts[i] -> xpro_type)
  2382.                     {
  2383.                         case XPRO_BOOLEAN:
  2384.  
  2385.                             if(SZ_GetChecked(GadgetArray[i]) != GetOptionMode(Opts[i]))
  2386.                             {
  2387.                                 Flags |= (1 << i);
  2388.  
  2389.                                 if(SZ_GetChecked(GadgetArray[i]))
  2390.                                     strcpy(Opts[i] -> xpro_value,"yes");
  2391.                                 else
  2392.                                     strcpy(Opts[i] -> xpro_value,"no");
  2393.  
  2394.                                 NewOptions = TRUE;
  2395.                             }
  2396.  
  2397.                             break;
  2398.  
  2399.                         case XPRO_COMMPAR:
  2400.                         case XPRO_LONG:
  2401.                         case XPRO_STRING:
  2402.  
  2403.                             if(strcmp(Opts[i] -> xpro_value,SZ_GetString(GadgetArray[i])))
  2404.                             {
  2405.                                 Flags |= (1 << i);
  2406.  
  2407.                                 strcpy(Opts[i] -> xpro_value,SZ_GetString(GadgetArray[i]));
  2408.  
  2409.                                 NewOptions = TRUE;
  2410.                             }
  2411.  
  2412.                             break;
  2413.                     }
  2414.                 }
  2415.             }
  2416.             else
  2417.             {
  2418.                 NewOptions    = FALSE;
  2419.                 Flags        = NULL;
  2420.             }
  2421.  
  2422.             ActiveGadget = NULL;
  2423.  
  2424.             RemoveGList(PanelWindow,GadgetList,(UWORD)-1);
  2425.  
  2426.             PopWindow();
  2427.  
  2428.             CloseWindow(PanelWindow);
  2429.         }
  2430.     }
  2431.  
  2432.     FreeGadgets(GadgetList);
  2433.  
  2434.     return(Flags);
  2435. }
  2436.  
  2437.     /* xpr_unlink(STRPTR FileName):
  2438.      *
  2439.      *    Remove (delete) a given file.
  2440.      */
  2441.  
  2442. LONG __saveds __asm
  2443. xpr_unlink(register __a0 STRPTR FileName)
  2444. {
  2445.         /* Sorry, but it is far too dangerous to let the protocol
  2446.          * remove any files with path name substitution enabled.
  2447.          * The protocol could accidentally hit the wrong file.
  2448.          */
  2449.  
  2450.     if(!Config -> MiscConfig -> OverridePath)
  2451.     {
  2452.         if(DeleteFile(FileName))
  2453.         {
  2454.             LogAction(LocaleString(MSG_TERMXPR_LOGMSG_DELETE_FILE_TXT),FilePart(FileName));
  2455.  
  2456.             return(0);
  2457.         }
  2458.     }
  2459.  
  2460.     return(-1);
  2461. }
  2462.  
  2463.     /* xpr_squery():
  2464.      *
  2465.      *    Check how many characters are present in the serial buffer.
  2466.      */
  2467.  
  2468. LONG __saveds __asm
  2469. xpr_squery()
  2470. {
  2471.     if(WriteRequest)
  2472.     {
  2473.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  2474.  
  2475.         DoIO(WriteRequest);
  2476.  
  2477.             /* Return error if carrier is lost. */
  2478.  
  2479.         if((WriteRequest -> io_Status & CIAF_COMCD) && Config -> SerialConfig -> CheckCarrier)
  2480.         {
  2481.             if(!CarrierMessage)
  2482.             {
  2483.                 CarrierMessage = TRUE;
  2484.  
  2485.                 AddTransferInfo(LocaleString(MSG_TERMXPR_CARRIER_LOST_TXT));
  2486.             }
  2487.  
  2488.             Online = FALSE;
  2489.  
  2490.             TransferError = TRUE;
  2491.         }
  2492.         else
  2493.             return((LONG)WriteRequest -> IOSer . io_Actual);
  2494.     }
  2495.  
  2496.     return(-1);
  2497. }
  2498.  
  2499.     /* xpr_getptr(LONG InfoType):
  2500.      *
  2501.      *    Return a pointer to the term custom screen.
  2502.      */
  2503.  
  2504. LONG __saveds __asm
  2505. xpr_getptr(register __d0 LONG InfoType)
  2506. {
  2507.     if(InfoType == 1)
  2508.         return((LONG)Window -> WScreen);
  2509.     else
  2510.         return(-1);
  2511. }
  2512.  
  2513.     /* xpr_stealopts(STRPTR Prompt,STRPTR Buffer):
  2514.      *
  2515.      *    Steal the contents of the options buffer (replacement
  2516.      *    for xpr_gets).
  2517.      */
  2518.  
  2519. LONG __saveds __asm
  2520. xpr_stealopts(register __a0 STRPTR Prompt,register __a1 STRPTR Buffer)
  2521. {
  2522.     if(Buffer)
  2523.         strcpy(ProtocolOptsBuffer,Buffer);
  2524.  
  2525.     return(1);
  2526. }
  2527.